package com.demo.java.OD351_400.OD394;

import java.util.Scanner;

/**
 * @author bug菌
 * @Source 公众号：猿圈奇妙屋
 * @des： 【机器人搬砖(C&D卷)】问题
 * @url： https://blog.csdn.net/weixin_43970743/article/details/146244034
 */
public class OdMain {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取砖块的重量信息
        String[] bricksString = scanner.nextLine().split(" ");
        int[] bricks = new int[bricksString.length];
        for (int i = 0; i < bricksString.length; i++) {
            bricks[i] = Integer.parseInt(bricksString[i]);
        }
        // 输出最小的最大工作时间
        System.out.println(minE(bricks, 8));
    }

    // 计算最小的最大工作时间
    public static int minE(int[] bricks, int H) {
        // 二分查找，找到最小的可以在H小时内完成的最大工作时间
        return binarySearch(bricks, 1, getMax(bricks), H);
    }

    // 获取砖块的最大重量
    private static int getMax(int[] bricks) {
        int max = Integer.MIN_VALUE;
        // 找到砖块中最大的重量
        for (int brick : bricks) {
            max = Math.max(max, brick);
        }
        return max;
    }

    // 检查是否可以在H小时内完成任务
    private static boolean canPaint(int[] bricks, int m, int H) {
        int sum = 0;
        // 计算每个砖块所需要的工作时间，假设每小时最多能搬运m个砖块
        for (int i : bricks) {
            sum += (i + m - 1) / m; // 计算搬运砖块的时间
        }
        // 如果总时间不超过H小时，则返回true
        return sum <= H;
    }

    // 二分查找最小的最大工作时间
    private static int binarySearch(int[] bricks, int l, int r, int H) {
        if (l > r) {
            return -1; // 如果没有找到合适的最大工作时间，返回-1
        }

        // 中间值
        int m = (l + r) / 2;
        // 如果能在H小时内完成任务，继续寻找更小的m
        if (canPaint(bricks, m, H)) {
            int result = binarySearch(bricks, l, m - 1, H);
            return result == -1 ? m : result; // 返回最小的m
        } else {
            // 如果不能完成任务，说明m太小，需要增大m
            return binarySearch(bricks, m + 1, r, H);
        }
    }
}